
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections.Generic;
using System.Text;

namespace Swaf.BizObj
{
	public enum MasterBaseBizObjListDisplayOption { mlOnly, blOnly, blended };
	public delegate IBizObj CreateBlankBase();
	public class MasterBaseBizObjList : BaseBizObjList
	{
		protected IBizObjList m_masterList = null;
		protected IBizObjList m_baseList = null;
		protected IBizObj m_newBaseListTypeBizObj = null;
		protected string m_baseListFieldNameforMaster = null;
		protected bool m_areSameTypes = false;
		protected MasterBaseBizObjListDisplayOption m_displayOption = MasterBaseBizObjListDisplayOption.blended;
		protected CreateBlankBase m_blankCreator = null;

		public MasterBaseBizObjList(MasterBaseBizObjListDisplayOption dispOption, IBizObjList masterList, IBizObjList baseList, string baseListFieldNameforMaster, CreateBlankBase blankCreator)
			:base(baseList.Name, baseList.objectType)
		{
			m_displayOption = dispOption;
			m_masterList = masterList;
			m_baseList = baseList;
			m_areSameTypes = (m_masterList.objectType.Name == m_baseList.objectType.Name && m_baseListFieldNameforMaster == null);
			m_baseListFieldNameforMaster = baseListFieldNameforMaster;
			m_blankCreator = blankCreator;
		}

		public override IBizObj this[int index]
		{
			get
			{
				IBizObj baseObj = null;
				if (UsingMaster)
				{
					IBizObj masterObj = m_masterList[index];
					if(m_displayOption == MasterBaseBizObjListDisplayOption.blended)
						if (m_areSameTypes)
							baseObj = m_baseList.search(m_baseList.objectType.KeyFieldNames, masterObj.KeyValue);
						else
							baseObj = m_baseList.search(m_baseListFieldNameforMaster + "." + masterObj.type.KeyFieldNames, masterObj.KeyValue, false);
					 
					if (baseObj == null)
						if (m_areSameTypes)
							baseObj = masterObj;
						else
						{
							baseObj = getNewBaseBizObj(false);
							baseObj.put(m_baseListFieldNameforMaster, masterObj);
							baseObj.put(baseObj.type.KeyFieldNames, masterObj.KeyValue);
						}
				}
				else
				{
					baseObj = m_baseList[index];
					if (m_masterList != null && !m_areSameTypes)
					{
						IBizObj masterObj = m_masterList.search(m_masterList.objectType.KeyFieldNames, baseObj.KeyValue);
						if (masterObj != null)
							baseObj.put(m_baseListFieldNameforMaster, masterObj);
					}
				}
				return baseObj;
			}
			set
			{
				throw new Exception("The method or operation is not implemented.");
			}
		}
		protected bool UsingMaster { get { return (m_displayOption == MasterBaseBizObjListDisplayOption.blended || m_displayOption == MasterBaseBizObjListDisplayOption.mlOnly); } }

		public MasterBaseBizObjListDisplayOption MasterVisibility { get { return m_displayOption; } set { m_displayOption = value; } }
		public IBizObjList BaseList { get { return m_baseList; } }
		public IBizObjList MasterList { get { return m_masterList; } set { m_masterList = value; } }
		protected IBizObj getNewBaseBizObj(bool cloneMasterIfNew) 
		{
			IBizObj newOne = m_newBaseListTypeBizObj;
			if (m_newBaseListTypeBizObj == null || cloneMasterIfNew)
				if (m_blankCreator == null)
					newOne = Application.currentApp.bizObjMgr.create(m_baseList.objectType.Name);
				else
					newOne = m_blankCreator();
			if (!cloneMasterIfNew)
				m_newBaseListTypeBizObj = newOne;

			return newOne;
		}

		public override IBizObj insertNew()
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override int numElements
		{
			get { return UsingMaster?m_masterList.numElements:m_baseList.numElements; }
		}

		public override IBizObj insertNewMakeCopy(IBizObj obj)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override void refresh()
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override string getXml(string name, string decoInfo, bool setOnly, bool dirtyOnly, bool newOnly, bool getBasic, bool getObjs, bool getILists, bool getSysVals, System.Xml.XmlTextWriter xmlOut)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override string getXml(string name, bool setOnly, bool dirtyOnly, bool newOnly, bool getBasic, bool getObjs, bool getILists, bool getSysVals, System.Xml.XmlTextWriter xmlOut)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override void removeAt(int index)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override IBizObjCursor createCursor()
		{
			return new basic.FullBizObjCursor(this);
		}

		public override IBizObj search(string fieldList, object matchValue, bool findNearestMatch)
		{
			return search(fieldList, matchValue, findNearestMatch, false);
		}

		public override IBizObj search(string fieldList, object matchValue)
		{
			return search(fieldList, matchValue, false, false);
		}

		public virtual IBizObj search(string fieldList, object matchValue, bool findNearestMatch, bool cloneMasterIfNew)
		{
			IBizObj baseObj = null;
			if (UsingMaster)
			{
				IBizObj masterObj = null;
				if(m_masterList != null && m_masterList.Count > 0 && m_masterList[0] != null)
					masterObj = m_masterList.search(fieldList, matchValue, findNearestMatch);

				if (m_displayOption == MasterBaseBizObjListDisplayOption.blended)
					if (m_areSameTypes || masterObj == null)
						baseObj = m_baseList.search(m_baseList.objectType.KeyFieldNames, matchValue);
					else
						baseObj = m_baseList.search(m_baseListFieldNameforMaster + "." + masterObj.type.KeyFieldNames, masterObj.KeyValue, false);
				if (baseObj == null)
					if (m_areSameTypes)
						baseObj = masterObj;
					else if (masterObj != null)
					{
						baseObj = getNewBaseBizObj(cloneMasterIfNew);
						baseObj.put(m_baseListFieldNameforMaster, masterObj);
						baseObj.put(baseObj.type.KeyFieldNames, masterObj.KeyValue);
					}
			}
			else
			{
				baseObj = m_baseList.search(fieldList, matchValue, findNearestMatch);
			}
			return baseObj;
		}

		public override object Clone()
		{
			throw new Exception("The method or operation is not implemented.");
		}

		public override void Clear()
		{
			m_baseList = null;
			m_masterList = null;
			m_newBaseListTypeBizObj = null;
		}
	}
}
